package com.vibration.baseinfo.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import ComputeMoreTemTwo.computeMoreTemTwo;
import ComputeTemOnePlot.computeTemOnePlot;
import ComputeXiEndMax.computeXiEndMax;
import ComputeXiEndMin.computeXiEndMin;
import com.mathworks.toolbox.javabuilder.MWClassID;
import com.mathworks.toolbox.javabuilder.MWNumericArray;
import com.vibration.baseinfo.domain.CzGroundWaterData;
import com.vibration.baseinfo.domain.CzGroundWaterResult;
import com.vibration.baseinfo.service.ICzGroundWaterDataService;
import com.vibration.baseinfo.service.ICzGroundWaterResultService;
import com.vibration.common.config.VibrationConfig;
import com.vibration.common.constant.Constants;
import com.vibration.common.utils.poi.ExcelUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.vibration.baseinfo.mapper.CzGroundWaterRecordMapper;
import com.vibration.baseinfo.domain.CzGroundWaterRecord;
import com.vibration.baseinfo.service.ICzGroundWaterRecordService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * 水脉分析记录Service业务层处理
 * 
 * @author Mr_wu
 * @date 2023-03-20
 */
@Service
public class CzGroundWaterRecordServiceImpl implements ICzGroundWaterRecordService 
{
    @Autowired
    private CzGroundWaterRecordMapper czGroundWaterRecordMapper;

    @Autowired
    private ICzGroundWaterDataService groundWaterDataService;

    @Autowired
    private ICzGroundWaterResultService groundWaterResultService;

    /**
     * 查询水脉分析记录
     * 
     * @param id 水脉分析记录主键
     * @return 水脉分析记录
     */
    @Override
    public CzGroundWaterRecord selectCzGroundWaterRecordById(Long id)
    {
        return czGroundWaterRecordMapper.selectCzGroundWaterRecordById(id);
    }

    /**
     * 查询水脉分析记录列表
     * 
     * @param czGroundWaterRecord 水脉分析记录
     * @return 水脉分析记录
     */
    @Override
    public List<CzGroundWaterRecord> selectCzGroundWaterRecordList(CzGroundWaterRecord czGroundWaterRecord)
    {
        return czGroundWaterRecordMapper.selectCzGroundWaterRecordList(czGroundWaterRecord);
    }

    /**
     * 新增水脉分析记录
     * 
     * @param czGroundWaterRecord 水脉分析记录
     * @return 结果
     */
    @Override
    public int insertCzGroundWaterRecord(CzGroundWaterRecord czGroundWaterRecord)
    {
        return czGroundWaterRecordMapper.insertCzGroundWaterRecord(czGroundWaterRecord);
    }

    /**
     * 修改水脉分析记录
     * 
     * @param czGroundWaterRecord 水脉分析记录
     * @return 结果
     */
    @Override
    @Transactional
    public int updateCzGroundWaterRecord(CzGroundWaterRecord czGroundWaterRecord) throws Exception
    {
        Long recordId=czGroundWaterRecord.getId();
        Long [] recordIds = {recordId};
        //删除原有分析结果，防止重新计算数据重复
        groundWaterResultService.deleteCzGroundWaterResultByRecordIds(recordIds);
        List<CzGroundWaterData> czGroundWaterDataList=groundWaterDataService.selectCzGroundWaterDataByRecordId(recordId);
        double[] x=new double[czGroundWaterDataList.size()];
        double[] y=new double[czGroundWaterDataList.size()];
        double[] T0=new double[czGroundWaterDataList.size()];
        double[] T1=new double[czGroundWaterDataList.size()];
        double[] water=new double[czGroundWaterDataList.size()];
        for (int i=0;i<czGroundWaterDataList.size();i++){
            x[i]=czGroundWaterDataList.get(i).getX().doubleValue();
            y[i]=czGroundWaterDataList.get(i).getY().doubleValue();
            T0[i]=czGroundWaterDataList.get(i).getT0().doubleValue();
            T1[i]=czGroundWaterDataList.get(i).getT1().doubleValue();
            water[i]=czGroundWaterDataList.get(i).getWater().doubleValue();
        }
        //阈值
        Double threshold=czGroundWaterRecord.getThreshold().doubleValue();

        Double thresholdMax=threshold;
        Double thresholdMin=czGroundWaterRecord.getThresholdmin().doubleValue();
        //水温
//        Double shuiwen=czGroundWaterRecord.getWaterTemperature().doubleValue();
        //横坐标
        MWNumericArray xDatamata = new MWNumericArray(x, MWClassID.DOUBLE);
        //纵坐标
        MWNumericArray yDatamata = new MWNumericArray(y, MWClassID.DOUBLE);
        //地表温度
        MWNumericArray T0Datamata = new MWNumericArray(T0, MWClassID.DOUBLE);
        //地下1m温度
        MWNumericArray T1Datamata = new MWNumericArray(T1, MWClassID.DOUBLE);

//        computeXiEnd computeXiEnd=new computeXiEnd();
//        Object[] respnseX= computeXiEnd.ComputeXiEnd(5,xDatamata,yDatamata,T0Datamata,T1Datamata,threshold);

        computeXiEndMax computeXiEndMax=new computeXiEndMax();
        computeXiEndMin computeXiEndMin=new computeXiEndMin();


        Object[] respnseXax=computeXiEndMax.ComputeXiEndMax(5,xDatamata,yDatamata,T0Datamata,T1Datamata,thresholdMax);


        /**
         * 得到距离的集合
         */
        MWNumericArray dMinDataMax=(MWNumericArray)respnseXax[0];
        double[][] dMinDataArrayMax=(double[][])dMinDataMax.toDoubleArray();
        double[] getDminDataMax=new double[dMinDataArrayMax[0].length];
        for (int i = 0; i <1 ; i++) {
            for (int j = 0; j <dMinDataArrayMax[0].length ; j++) {
                getDminDataMax[j]=dMinDataArrayMax[i][j];
            }
        }


        /**
         * 得到T0'
         */
        MWNumericArray T0ComPuteDataMax=(MWNumericArray)respnseXax[1];
        double[][] T0ComPuteDataArrayMax=(double[][])T0ComPuteDataMax.toDoubleArray();
        double[] getT0ComPuteDataArrayMax=new double[T0ComPuteDataArrayMax[0].length];
        for (int i = 0; i <1 ; i++) {
            for (int j = 0; j <T0ComPuteDataArrayMax[0].length ; j++) {
                getT0ComPuteDataArrayMax[j]=T0ComPuteDataArrayMax[i][j];
            }
        }

        /**
         * 得到Tb的集合
         */
        MWNumericArray T0DataMax=(MWNumericArray)respnseXax[2];
        double[][] T0DataArrayMax=(double[][])T0DataMax.toDoubleArray();
        double[] getT0AllDataMax=new double[T0DataArrayMax[0].length];
        for (int i = 0; i <1 ; i++) {
            for (int j = 0; j <T0DataArrayMax[0].length ; j++) {
                getT0AllDataMax[j]=T0DataArrayMax[i][j];
            }
        }
        double[] TbDataMax=new double[getT0AllDataMax.length];
        for (int i = 0; i < TbDataMax.length; i++) {
            TbDataMax[i]=water[i]-getT0AllDataMax[i];
        }

        /**
         * 输入阈值与水温进行计算
         */
        Object[] respnseXim=computeXiEndMin.ComputeXiEndMin(5,xDatamata,yDatamata,T0Datamata,T1Datamata,thresholdMin);

        /**
         * 得到距离的集合
         */
        MWNumericArray dMinDataMin=(MWNumericArray)respnseXim[0];
        double[][] dMinDataArrayMin=(double[][])dMinDataMin.toDoubleArray();
        double[] getDminDataMin=new double[dMinDataArrayMin[0].length];
        for (int i = 0; i <1 ; i++) {
            for (int j = 0; j <dMinDataArrayMin[0].length ; j++) {
                getDminDataMin[j]=dMinDataArrayMin[i][j];
            }
        }


        /**
         * 得到T0'
         */
        MWNumericArray T0ComPuteDataMin=(MWNumericArray)respnseXim[1];
        double[][] T0ComPuteDataArrayMin=(double[][])T0ComPuteDataMin.toDoubleArray();
        double[] getT0ComPuteDataArrayMin=new double[T0ComPuteDataArrayMin[0].length];
        for (int i = 0; i <1 ; i++) {
            for (int j = 0; j <T0ComPuteDataArrayMin[0].length ; j++) {
                getT0ComPuteDataArrayMin[j]=T0ComPuteDataArrayMin[i][j];
            }
        }

        /**
         * 得到Tb的集合
         */
        MWNumericArray T0DataMin=(MWNumericArray)respnseXim[2];
        double[][] T0DataArrayMin=(double[][])T0DataMin.toDoubleArray();
        double[] getT0AllDataMin=new double[T0DataArrayMin[0].length];
        for (int i = 0; i <1 ; i++) {
            for (int j = 0; j <T0DataArrayMin[0].length ; j++) {
                getT0AllDataMin[j]=T0DataArrayMin[i][j];
            }
        }
        double[] TbDataMin=new double[getT0AllDataMin.length];
        for (int i = 0; i < TbDataMin.length; i++) {
            TbDataMin[i]=water[i]-getT0AllDataMin[i];
        }

        /**
         * 进行极大值和极小值的合并
         */
        //距离集合
        double[] getDminDataAll = Arrays.copyOf(getDminDataMax, getDminDataMax.length + getDminDataMin.length);
        System.arraycopy(getDminDataMin, 0, getDminDataAll, getDminDataMax.length, getDminDataMin.length);

        //极值点集合
        double[] getT0ComPuteDataArrayAll = Arrays.copyOf(getT0ComPuteDataArrayMax, getT0ComPuteDataArrayMax.length + getT0ComPuteDataArrayMin.length);
        System.arraycopy(getT0ComPuteDataArrayMin, 0, getT0ComPuteDataArrayAll, getT0ComPuteDataArrayMax.length, getT0ComPuteDataArrayMin.length);

        double[] TbDataAll=Arrays.copyOf(TbDataMax, TbDataMax.length + TbDataMin.length);
        System.arraycopy(TbDataMin, 0, TbDataAll, TbDataMax.length, TbDataMin.length);


        //深度list集合
        double[] hdataList=new double[getDminDataAll.length];
        //半径list集合
        double[] rdataList=new double[getDminDataAll.length];
        //a list集合
        double[] adataList=new double[getDminDataAll.length];

        for (int i = 0; i < getDminDataAll.length; i++) {
            computeMoreTemTwo computeMoreTemTwo=new computeMoreTemTwo();
            Object[] responseY= computeMoreTemTwo.ComputeMoreTemTwo(3,getDminDataAll[i],getT0ComPuteDataArrayAll[i],TbDataAll[i]);
            //得到a
            MWNumericArray aData=(MWNumericArray)responseY[0];
            double[][] aDataArray=(double[][])aData.toDoubleArray();
            double a=aDataArray[0][0];
            adataList[i]=a;
            //得到h
            MWNumericArray hData=(MWNumericArray)responseY[1];
            double[][] hDataArray=(double[][])hData.toDoubleArray();
            double h=hDataArray[0][0];
            hdataList[i]=h;
            //得到半径
            MWNumericArray rData=(MWNumericArray)responseY[2];
            double[][] rDataArray=(double[][])rData.toDoubleArray();
            double r=rDataArray[0][0];
            rdataList[i]=r;
        }



        List<CzGroundWaterResult> resultList = new ArrayList<>();

        for (int i=0;i<hdataList.length;i++){
            CzGroundWaterResult czGroundWaterResult=new CzGroundWaterResult();
            czGroundWaterResult.setRecordId(recordId);
            czGroundWaterResult.setXi(new BigDecimal(getDminDataAll[i]));
            czGroundWaterResult.setA(new BigDecimal(adataList[i]));
            czGroundWaterResult.setR(new BigDecimal(hdataList[i]));
            czGroundWaterResult.setH(new BigDecimal(rdataList[i]));
            czGroundWaterResult.setTb(new BigDecimal(TbDataAll[i]));
            czGroundWaterResult.setT0(new BigDecimal(getT0ComPuteDataArrayAll[i]));
            resultList.add(czGroundWaterResult);
        }
        groundWaterResultService.batchInsertGroundWaterResult(resultList);
        //计算状态赋值为已分析
        czGroundWaterRecord.setCalcStatus("2");
        return czGroundWaterRecordMapper.updateCzGroundWaterRecord(czGroundWaterRecord);
    }

    /**
     * 批量删除水脉分析记录
     * 
     * @param ids 需要删除的水脉分析记录主键
     * @return 结果
     */
    @Override
    public int deleteCzGroundWaterRecordByIds(Long[] ids)
    {
        return czGroundWaterRecordMapper.deleteCzGroundWaterRecordByIds(ids);
    }

    /**
     * 删除水脉分析记录信息
     * 
     * @param id 水脉分析记录主键
     * @return 结果
     */
    @Override
    public int deleteCzGroundWaterRecordById(Long id)
    {
        return czGroundWaterRecordMapper.deleteCzGroundWaterRecordById(id);
    }

    @Override
    @Transactional
    public CzGroundWaterRecord importWaterData(MultipartFile file,CzGroundWaterRecord czGroundWaterRecord)throws Exception {

        czGroundWaterRecord.setCalcStatus("0");
        //存储分析记录
        int count=czGroundWaterRecordMapper.insertCzGroundWaterRecord(czGroundWaterRecord);
        Long recordId=czGroundWaterRecord.getId();

        //获取导入温度数据
        ExcelUtil<CzGroundWaterData> util = new ExcelUtil<CzGroundWaterData>(CzGroundWaterData.class);
        List<CzGroundWaterData> dataList = util.importExcel(file.getInputStream());

        //批量插入
        groundWaterDataService.batchInsertGroundWaterData(recordId,dataList);

        /*Workbook workbook = WorkbookFactory.create(file.getInputStream());
        Sheet hssfSheet = workbook.getSheetAt(0);//每一个工作簿
        //循环行
        for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
            Row hssfRow = hssfSheet.getRow(rowNum);//每一行
            if (hssfRow== null) {
                continue;
            }
            CzGroundWaterData czGroundWaterData=new CzGroundWaterData();
            czGroundWaterData.setRecordId(recordId);
            //循环列
            czGroundWaterData.setNumber(hssfRow.getCell(0).toString());
            czGroundWaterData.setT0(new BigDecimal(hssfRow.getCell(1).toString()));
            czGroundWaterData.setT1(new BigDecimal(hssfRow.getCell(2).toString()));
            czGroundWaterData.setX(new BigDecimal(hssfRow.getCell(3).toString()));
            czGroundWaterData.setY(new BigDecimal(hssfRow.getCell(4).toString()));
            czGroundWaterDataService.insertCzGroundWaterData(czGroundWaterData);
        }
        List<CzGroundWaterData> czGroundWaterDataList=czGroundWaterDataService.selectCzGroundWaterDataByRecordId(recordId);*/

        //处理数据生成等值线图
        double[] x=new double[dataList.size()];
        double[] y=new double[dataList.size()];
        double[] T1=new double[dataList.size()];
        for (int i=0;i<dataList.size();i++){
            x[i]=dataList.get(i).getX().doubleValue();
            y[i]=dataList.get(i).getY().doubleValue();
            T1[i]=dataList.get(i).getT1().doubleValue();
        }
        //横坐标
        MWNumericArray xDatamata = new MWNumericArray(x, MWClassID.DOUBLE);
        //纵坐标
        MWNumericArray yDatamata = new MWNumericArray(y, MWClassID.DOUBLE);
        //地下1m温度
        MWNumericArray T1Datamata = new MWNumericArray(T1, MWClassID.DOUBLE);
        //生成图片路径
//        String filePath="E://testMatlab/images/";
        //生成图片名称
        String fileName="ComputeTwoPlot";
        String filePath= VibrationConfig.getMoreTempPath()+"/"+recordId+"/";
        //如果目录不存在则创建
        java.io.File desc = new java.io.File(filePath+"ComputeTwoPlot.jpg");
        if (!desc.exists())
        {
            if (!desc.getParentFile().exists())
            {
                desc.getParentFile().mkdirs();
            }
        }
        computeTemOnePlot computeTemOnePlot=new computeTemOnePlot();
        computeTemOnePlot.ComputeTemOnePlot(xDatamata,yDatamata,T1Datamata,filePath,fileName);
        filePath= Constants.RESOURCE_PREFIX+VibrationConfig.getMoreTempPath2()+"/"+recordId+"/";
        czGroundWaterRecord.setFilePath(czGroundWaterRecord.getFilePath()+filePath+"ComputeTwoPlot.jpg");
        czGroundWaterRecordMapper.updateCzGroundWaterRecord(czGroundWaterRecord);
        return czGroundWaterRecord;
    }
}
